#include <stdexcept>

#include "operon.h"

using namespace std;



const Organism* Organism::HOMO_SAPIENS= new Organism("Homo sapiens",9606,1,"hsa");
const Organism* Organism::MUS_MUSCULUS= new Organism("Mus Musculus",10090,2,"mmu");

const Assembly* Assembly::HSA_NCBI_BUILD_36=new Assembly(1,"ref",Organism::HOMO_SAPIENS,"36","NCBI Homo-Sapiens Reference build 36");

/**
 * Organism
 */		
Organism::Organism(const char *s,int tax,int id,const char* w3):name(s),letter3(w3),tax_id(tax),operon_id(id)
			{
			}
			
const char* Organism::getName() const
	{
	return name.c_str();
	}

const char* Organism::getTreeLetterCode() const
	{
	return letter3.c_str();
	}

int Organism::getTaxId() const
	{
	return tax_id;
	}
	
int Organism::getOperonId() const
	{
	return operon_id;
	}
	
/**
 * Assembly
 */
Assembly::Assembly(int _id,std::string _source,const Organism* _organism, std::string _version,std::string _longDesc):
	organism(_organism),source(_source),version(_version),longDesc(_longDesc),id(_id)
	{
	
	}
const Organism* Assembly::getOrganism() const
	{
	return organism;
	}

const char* Assembly::getVersion() const
	{
	return version.c_str();
	}
const char* Assembly::getSource() const
	{
	return source.c_str();
	}
const char* Assembly::getName() const
	{
	return longDesc.c_str();
	}

/**
 * AbstractEntity
 */
AbstractEntity::AbstractEntity()
	{
	}

void AbstractEntity::json(std::ostream& out,const char* s)
	{
	char* p=(char*)s;
	while(*p!=0)
		{
		switch(*p)
			{
			case '\'':out << "\\\'"; break;
			case '\"':out << "\\\""; break;
			case '\\':out << "\\\\"; break;
			case '\n':out << "\\n"; break;
			case '\r':out << "\\r"; break;
			case '\t':out << "\\t"; break;
			default: out << (*p); break;
			}
		++p;
		}
	}

/**
 * Operon
 */
Operon::Operon(const char* bbd_home):db_home(bbd_home),env(0)
	{
	}
		
DbEnv* Operon::getEnvironment()
	{
	return env;
	}

const char* Operon::getHome() const
	{
	return db_home.c_str();
	}

Operon::~Operon()
	{
	close();
	}
	
void Operon::open() throw(std::exception)
	{
	
	if(env!=0) return;
	try
		{
		env= new DbEnv(0);
		env->open(db_home.c_str(),0,0);
		}
	catch(...)
		{
		
		close();
		throw std::runtime_error("Cannot open operon");
		}
	}
void Operon::close()throw(std::exception)
	{
	if(env!=0)
		{
		try {env->close(0); } catch(...) {}
		delete env;
		}
	env=0;
	}
